#pragma once

#include <iostream>
#include <functional>
#include <string>
#include "sock.hpp"

class Http_server
{
    using func_t = std::function<void(int)>;

public:
    Http_server(const uint16_t &port, func_t func) : _port(port), _func(func)
    {
        // 获取监听套接字、绑定and监听
        _listensock = _sock.CreateSocket();
        _sock.Bind(_listensock, _port);
        _sock.Listen(_listensock);
    }
    void Start()
    {
        while (1)
        {
            std::string clientip;
            uint16_t clientport;
            int serversock = _sock.Accept(_listensock, &clientip, &clientport);
            if(serversock < 0)
                continue;    //连接失败就继续等待连接
            pid_t pid = fork();
            if (pid < 0)
            {
                // 创建失败
                exit(-1);
            }
            else if (pid == 0)
            {
                // 子进程
                close(_listensock);
                _func(serversock);
                close(serversock);
                exit(0);     //执行完就退出
            }
            close(serversock);
        }
    }

    ~Http_server()
    {
        if(_listensock >= 0)
            close(_listensock);    //防止文件描述符泄露
    }

private:
    int _listensock; // 监听sock(文件描述符)
    uint16_t _port;
    Sock _sock; // 用于创建套接字并使用
    func_t _func;
};